package com.teradata.olingo.processor.core.filter;

import org.apache.olingo.server.api.ODataApplicationException;
import org.apache.olingo.server.api.uri.queryoption.expression.BinaryOperatorKind;

import javax.persistence.criteria.Expression;

//
public class GenericComparisonOperatorImp<T extends Comparable<T>> implements GenericComparisonOperator<T> {
  private final GenericOperationConverter converter;
  private final BinaryOperatorKind operator;
  private final GenericOperator left;
  private final GenericOperator right;

  public GenericComparisonOperatorImp(final GenericOperationConverter converter, final BinaryOperatorKind operator,
                                      final GenericOperator left,
                                      final GenericOperator right) {
    super();
    this.converter = converter;
    this.operator = operator;
    this.left = left;
    this.right = right;
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#get()
   */
  @Override
  public Expression<Boolean> get() throws ODataApplicationException {
    return converter.convert(this);
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#getOperator()
   */
  @SuppressWarnings("unchecked")
  @Override
  public BinaryOperatorKind getOperator() {
    return operator;
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#getLeft()
   */
  @Override
  @SuppressWarnings("unchecked")
  public Expression<T> getLeft() throws ODataApplicationException {
    if (left instanceof GenericLiteralOperator)
      return (Expression<T>) right.get();
    return (Expression<T>) left.get();
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#getRight()
   */
  @Override
  public Object getRight() {
    if (left instanceof GenericLiteralOperator)
      return left;
    return right;
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#getRightAsComparable()
   */
  @Override
  @SuppressWarnings("unchecked")
  public Comparable<T> getRightAsComparable() throws ODataApplicationException {
    if (left instanceof GenericLiteralOperator) {
      if (right instanceof GenericMemberOperator)
        return (Comparable<T>) ((GenericLiteralOperator) left).get(((GenericMemberOperator) right).determineAttribute());
      else
        return (Comparable<T>) left.get();
    }
    if (right instanceof GenericLiteralOperator) {
      if (left instanceof GenericMemberOperator)
        return (Comparable<T>) ((GenericLiteralOperator) right).get(((GenericMemberOperator) left).determineAttribute());

      else {
        return (Comparable<T>) right.get();
      }
    }
    return (Comparable<T>) right.get();
  }

  /*
   * (non-Javadoc)
   * 
   * @see GenericComparisonOperator#getRightAsExpression()
   */
  @Override
  @SuppressWarnings("unchecked")
  public Expression<T> getRightAsExpression() throws ODataApplicationException {
    return (Expression<T>) right.get();
  }
}